<html>
<head>
<script src="http://code.jquery.com/jquery-1.8.2.js"></script>
<script src="http://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1','packages':['controls', 'charteditor']}]}"></script>
<script src="http://jquery-csv.googlecode.com/git/src/jquery.csv.js"></script>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script>
$(function() {
	google.load("visualization", "1", {packages:["corechart"]});

    var csv = $('#textInput').val();
    var data = $.csv.toArrays(csv, {
        onParseValue: $.csv.hooks.castToScalar
    });

    // Convert data for bar chart (summing all digits)
    var timeData = {};	// type -> table
    var funcRowMap;
    var maxDigit = 0;

    for (var i = 1; i < data.length; i++) {
    	var type = data[i][0];
   		var func = data[i][1];
      var digit = data[i][2];
   		var time = data[i][3];
   		if (timeData[type] == null) {
   			timeData[type] = [["Function", "Time (ns)"/*, { role: "style" }*/]];
        if (digit != 0)
   			  funcRowMap = {};
   		}

   		var table = timeData[type];
   		
      if (digit != 0) {
     		if (funcRowMap[func] == null)
     			funcRowMap[func] = table.push([func, 0]) - 1;
     		
     		table[funcRowMap[func]][1] += time;
      }
      else 
        table.push([func, time]);

      maxDigit = Math.max(maxDigit, digit);
    }

    // Compute average
    for (var type in timeData) {
      var table = timeData[type];
      for (var i = 1; i < table.length; i++)
        table[i][1] /= maxDigit;
    }

    // Convert data for drawing line chart per random digit
    var timeDigitData = {}; // type -> table
    var funcColumnMap;

    for (var i = 1; i < data.length; i++) {
    	var type = data[i][0];
   		var func = data[i][1];
		  var digit = data[i][2];
   		var time = data[i][3];

      if (digit == 0)
        continue;

   		if (timeDigitData[type] == null) {
   			timeDigitData[type] = [["Digit"]];
   			funcColumnMap = {};
   		}

   		var table = timeDigitData[type];

   		if (funcColumnMap[func] == null)
   			funcColumnMap[func] = table[0].push(func) - 1;

   		var row;
   		for (row = 1; row < table.length; row++)
   			if (table[row][0] == digit)
   				break;

    	if (row == table.length)
    		table.push([digit]);

		table[row][funcColumnMap[func]] = time;
	}

	for (var type in timeData) {
		$("#main").append(
      $("<a>", {name: type}),
      $("<h2>", {style: "padding-top: 70px; margin-top: -70px;"}).append(type)
    );

    $("#section").append($("<li>").append($("<a>", {href: "#" + type}).append(type)));

		drawTable(type, timeData[type]);
		drawBarChart(type, timeData[type]);
    if (timeDigitData[type] != null)
		  drawDigitChart(type, timeDigitData[type]);
	}

	$(".chart").each(function() {
		var chart = $(this);
		var d = $("#downloadDD").clone().css("display", "");
		$('li a', d).each(function() {
	        $(this).click(function() {
	            var svg = chart[0].getElementsByTagName('svg')[0].parentNode.innerHTML;
	            svg=sanitize(svg);
	            $('#imageFilename').val($("#title").html() + "_" + chart.data("filename"));
	            $('#imageGetFormTYPE').val($(this).attr('dltype'));
	            $('#imageGetFormSVG').val(svg);
	            $('#imageGetForm').submit();
	        });
	    });		
		$(this).after(d);
	});

  // Add configurations
  var thisConfig = "corei7920@2.67_win64_vc2013";
  var configurations = ["corei7920@2.67_cygwin32_gcc4.8","corei7920@2.67_cygwin64_gcc4.8","corei7920@2.67_win32_vc2013","corei7920@2.67_win64_vc2013"];

  for (var i in configurations) {
    var c = configurations[i];
    $("#configuration").append($("<li>", {class : (c == thisConfig ? "active" : "")}).append($("<a>", {href: c + ".html"}).append(c)));
  }
});

function drawTable(type, timeData) {
	var data = google.visualization.arrayToDataTable(timeData);
    data.addColumn('number', 'Speedup');
    data.sort([{ column: 1, desc: true }]);
    var formatter1 = new google.visualization.NumberFormat({ fractionDigits: 3 });
    formatter1.format(data, 1);

	var div = document.createElement("div");
	div.className = "tablechart";
	$("#main").append(div);
    var table = new google.visualization.Table(div);
    redrawTable(0);
    table.setSelection([{ row: 0, column: null}]);

    function redrawTable(selectedRow) {
        // Compute relative time using the first row as basis
        var basis = data.getValue(selectedRow, 1);
        for (var rowIndex = 0; rowIndex < data.getNumberOfRows(); rowIndex++)
            data.setValue(rowIndex, 2, basis / data.getValue(rowIndex, 1));

        var formatter = new google.visualization.NumberFormat({suffix: 'x'});
        formatter.format(data, 2); // Apply formatter to second column

        table.draw(data);
    }

    google.visualization.events.addListener(table, 'select',
    function() {
        var selection = table.getSelection();
        if (selection.length > 0) {
            var item = selection[0];
            if (item.row != null)
                redrawTable(item.row);
        }
    });

}

function drawBarChart(type, timeData) {
    var defaultColors = ["#3366cc","#dc3912","#ff9900","#109618","#990099","#0099c6","#dd4477","#66aa00","#b82e2e","#316395","#994499","#22aa99","#aaaa11","#6633cc","#e67300","#8b0707","#651067","#329262","#5574a6","#3b3eac","#b77322","#16d620","#b91383","#f4359e","#9c5935","#a9c413","#2a778d","#668d1c","#bea413","#0c5922","#743411"];

	var data = google.visualization.arrayToDataTable(timeData);
	data.addColumn({ type: "string", role: "style" })
	for (var rowIndex = 0; rowIndex < data.getNumberOfRows(); rowIndex++)
		data.setValue(rowIndex, 2, defaultColors[rowIndex]);

    data.sort([{ column: 1, desc: true }]);
	var options = { 
		title: type,
		chartArea: {'width': '70%', 'height': '70%'},
		width: 800,
		height: 300,
		legend: { position: "none" },
		hAxis: { title: "Time (ns)" }
	};
	var div = document.createElement("div");
	div.className = "chart";
	$(div).data("filename", type + "_time");
	$("#main").append(div);
	var chart = new google.visualization.BarChart(div);

	chart.draw(data, options);
}

function drawDigitChart(type, timeDigitData) {
	var data = google.visualization.arrayToDataTable(timeDigitData);

	var options = { 
		title: type,
		chartArea: {'width': '70%', 'height': '80%'},
		hAxis: {
			title: "Digit",
			gridlines: { count: timeDigitData.length - 1 },
			maxAlternation: 1,
			minTextSpacing: 0
		},
		vAxis: {
			title: "Time (ns) in log scale",
			logScale: true,
			minorGridlines: { count: 10 },
      baseline: 0
		},
		width: 800,
		height: 600
	};
	var div = document.createElement("div");
	div.className = "chart";
	$(div).data("filename", type + "_timedigit");
	$("#main").append(div);
	var chart = new google.visualization.LineChart(div);

	chart.draw(data, options);
}

// http://jsfiddle.net/P6XXM/
function sanitize(svg) {
    svg = svg
        .replace(/\<svg/,'<svg xmlns="http://www.w3.org/2000/svg" version="1.1"')
        .replace(/zIndex="[^"]+"/g, '')
        .replace(/isShadow="[^"]+"/g, '')
        .replace(/symbolName="[^"]+"/g, '')
        .replace(/jQuery[0-9]+="[^"]+"/g, '')
        .replace(/isTracker="[^"]+"/g, '')
        .replace(/url\([^#]+#/g, 'url(#')
        .replace('<svg xmlns:xlink="http://www.w3.org/1999/xlink" ', '<svg ')
        .replace(/ href=/g, ' xlink:href=')
    /*.replace(/preserveAspectRatio="none">/g, 'preserveAspectRatio="none"/>')*/
    /* This fails in IE < 8
    .replace(/([0-9]+)\.([0-9]+)/g, function(s1, s2, s3) { // round off to save weight
    return s2 +'.'+ s3[0];
    })*/

    // IE specific
        .replace(/id=([^" >]+)/g, 'id="$1"')
        .replace(/class=([^" ]+)/g, 'class="$1"')
        .replace(/ transform /g, ' ')
        .replace(/:(path|rect)/g, '$1')
        .replace(/<img ([^>]*)>/gi, '<image $1 />')
        .replace(/<\/image>/g, '') // remove closing tags for images as they'll never have any content
        .replace(/<image ([^>]*)([^\/])>/gi, '<image $1$2 />') // closes image tags for firefox
        .replace(/width=(\d+)/g, 'width="$1"')
        .replace(/height=(\d+)/g, 'height="$1"')
        .replace(/hc-svg-href="/g, 'xlink:href="')
        .replace(/style="([^"]+)"/g, function (s) {
            return s.toLowerCase();
        });

    // IE9 beta bugs with innerHTML. Test again with final IE9.
    svg = svg.replace(/(url\(#highcharts-[0-9]+)&quot;/g, '$1')
        .replace(/&quot;/g, "'");
    if (svg.match(/ xmlns="/g).length == 2) {
        svg = svg.replace(/xmlns="[^"]+"/, '');
    }

    return svg;
}
</script>
<style type="text/css">
@media (min-width: 800px) {
  .container {
    max-width: 800px;
  }
}
textarea {
	font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
}
.tablechart {
	width: 700px;
	margin: auto;
	padding-top: 20px;
	padding-bottom: 20px;
}
.chart {
	padding-top: 20px;
	padding-bottom: 20px;
}
body { padding-top: 70px; }
</style>
</head>
<body>
<div class="container">
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
  <div class="container">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="https://github.com/miloyip/dtoa-benchmark"><span class="glyphicon glyphicon-home"></span> dtoa-benchmark</a>
    </div>

    <!-- Collect the nav links, forms, and other content for toggling -->
    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav">
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Configuration <span class="caret"></span></a>
          <ul class="dropdown-menu" role="menu" id="configuration">
          </ul>
        </li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Section <span class="caret"></span></a>
          <ul class="dropdown-menu" role="menu" id="section">
          </ul>
        </li>
      </ul>
      <p class="navbar-text navbar-right">Developed by <a href="https://github.com/miloyip" class="navbar-link">Milo Yip</a></p>
    </div><!-- /.navbar-collapse -->
  </div><!-- /.container-fluid -->
</nav>
<div class="page-header">
<h1 id="title">corei7920@2.67_win64_vc2013</h1>
</div>
<div id="main"></div>
<h2>Source CSV</h2>
<textarea id="textInput" class="form-control" rows="5" readonly>
doubleype,Function,Digit,doubleime(ms)
randomdigit,doubleconv,1,150.037259
randomdigit,doubleconv,2,165.439057
randomdigit,doubleconv,3,170.477207
randomdigit,doubleconv,4,180.158884
randomdigit,doubleconv,5,185.319635
randomdigit,doubleconv,6,194.928518
randomdigit,doubleconv,7,192.384539
randomdigit,doubleconv,8,202.123686
randomdigit,doubleconv,9,200.759745
randomdigit,doubleconv,10,209.280541
randomdigit,doubleconv,11,205.725101
randomdigit,doubleconv,12,220.851045
randomdigit,doubleconv,13,215.713281
randomdigit,doubleconv,14,231.283656
randomdigit,doubleconv,15,224.509930
randomdigit,doubleconv,16,232.858317
randomdigit,doubleconv,17,246.106928
randomdigit,fpconv,1,194.510907
randomdigit,fpconv,2,216.548503
randomdigit,fpconv,3,232.636102
randomdigit,fpconv,4,246.907668
randomdigit,fpconv,5,257.179364
randomdigit,fpconv,6,266.205890
randomdigit,fpconv,7,272.964290
randomdigit,fpconv,8,281.071306
randomdigit,fpconv,9,283.488852
randomdigit,fpconv,10,288.707073
randomdigit,fpconv,11,292.277838
randomdigit,fpconv,12,294.883117
randomdigit,fpconv,13,297.480733
randomdigit,fpconv,14,300.300565
randomdigit,fpconv,15,302.859869
randomdigit,fpconv,16,308.982275
randomdigit,fpconv,17,317.966656
randomdigit,gay,1,612.650546
randomdigit,gay,2,740.995025
randomdigit,gay,3,881.258656
randomdigit,gay,4,1005.266112
randomdigit,gay,5,1125.633840
randomdigit,gay,6,1248.258198
randomdigit,gay,7,1368.300266
randomdigit,gay,8,1495.185023
randomdigit,gay,9,1616.928184
randomdigit,gay,10,1739.502737
randomdigit,gay,11,1915.148357
randomdigit,gay,12,2076.472605
randomdigit,gay,13,2196.399734
randomdigit,gay,14,2312.966819
randomdigit,gay,15,2432.445687
randomdigit,gay,16,2576.004230
randomdigit,gay,17,2643.852595
randomdigit,grisu2,1,177.055537
randomdigit,grisu2,2,188.702667
randomdigit,grisu2,3,198.330706
randomdigit,grisu2,4,200.955141
randomdigit,grisu2,5,201.947446
randomdigit,grisu2,6,207.223136
randomdigit,grisu2,7,210.705782
randomdigit,grisu2,8,217.678735
randomdigit,grisu2,9,220.004329
randomdigit,grisu2,10,226.919813
randomdigit,grisu2,11,227.804842
randomdigit,grisu2,12,234.996178
randomdigit,grisu2,13,236.038290
randomdigit,grisu2,14,241.130078
randomdigit,grisu2,15,245.294693
randomdigit,grisu2,16,248.627918
randomdigit,grisu2,17,260.845911
randomdigit,milo,1,92.905020
randomdigit,milo,2,106.590398
randomdigit,milo,3,117.214573
randomdigit,milo,4,122.923200
randomdigit,milo,5,125.306264
randomdigit,milo,6,131.543609
randomdigit,milo,7,134.639293
randomdigit,milo,8,139.899658
randomdigit,milo,9,143.160089
randomdigit,milo,10,144.960796
randomdigit,milo,11,147.033526
randomdigit,milo,12,150.937613
randomdigit,milo,13,152.949042
randomdigit,milo,14,154.864688
randomdigit,milo,15,155.807186
randomdigit,milo,16,160.328112
randomdigit,milo,17,165.297299
randomdigit,null,1,2.145524
randomdigit,null,2,2.145524
randomdigit,null,3,2.145524
randomdigit,null,4,2.145524
randomdigit,null,5,2.145524
randomdigit,null,6,2.145524
randomdigit,null,7,2.145524
randomdigit,null,8,2.145524
randomdigit,null,9,2.145524
randomdigit,null,10,2.145524
randomdigit,null,11,2.145524
randomdigit,null,12,2.145524
randomdigit,null,13,2.145524
randomdigit,null,14,2.145524
randomdigit,null,15,2.145524
randomdigit,null,16,2.145524
randomdigit,null,17,2.145524
randomdigit,ostringstream,1,2725.930382
randomdigit,ostringstream,2,2733.416728
randomdigit,ostringstream,3,2728.409228
randomdigit,ostringstream,4,2738.684755
randomdigit,ostringstream,5,2756.170776
randomdigit,ostringstream,6,2751.672838
randomdigit,ostringstream,7,2759.473350
randomdigit,ostringstream,8,2757.599848
randomdigit,ostringstream,9,2774.492018
randomdigit,ostringstream,10,2793.728940
randomdigit,ostringstream,11,2795.288276
randomdigit,ostringstream,12,2806.920081
randomdigit,ostringstream,13,2811.483151
randomdigit,ostringstream,14,2819.456071
randomdigit,ostringstream,15,2833.440290
randomdigit,ostringstream,16,2834.524546
randomdigit,ostringstream,17,2818.023168
randomdigit,ostrstream,1,2578.214886
randomdigit,ostrstream,2,2574.460219
randomdigit,ostrstream,3,2594.202871
randomdigit,ostrstream,4,2595.118550
randomdigit,ostrstream,5,2610.696587
randomdigit,ostrstream,6,2609.987797
randomdigit,ostrstream,7,2619.228876
randomdigit,ostrstream,8,2612.646715
randomdigit,ostrstream,9,2626.473850
randomdigit,ostrstream,10,2642.496317
randomdigit,ostrstream,11,2641.829672
randomdigit,ostrstream,12,2651.300628
randomdigit,ostrstream,13,2654.948019
randomdigit,ostrstream,14,2652.856133
randomdigit,ostrstream,15,2683.096528
randomdigit,ostrstream,16,2670.326828
randomdigit,ostrstream,17,2664.323193
randomdigit,sprintf,1,1224.186186
randomdigit,sprintf,2,1225.856629
randomdigit,sprintf,3,1240.132026
randomdigit,sprintf,4,1236.618731
randomdigit,sprintf,5,1252.874906
randomdigit,sprintf,6,1250.668082
randomdigit,sprintf,7,1253.177579
randomdigit,sprintf,8,1251.855782
randomdigit,sprintf,9,1255.909290
randomdigit,sprintf,10,1254.733083
randomdigit,sprintf,11,1253.690972
randomdigit,sprintf,12,1256.392033
randomdigit,sprintf,13,1261.801819
randomdigit,sprintf,14,1258.277029
randomdigit,sprintf,15,1267.311218
randomdigit,sprintf,16,1313.436152
randomdigit,sprintf,17,1301.463362
</textarea>
</div>
<div class="row" id="downloadDD" style="display: none">
<div class="btn-group pull-right" >
    <button class="btn dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-picture"></span></button>
    <ul class="dropdown-menu">
        <li><a tabindex="-1" href="#" dltype="image/jpeg">JPEG</a></li>
        <li><a tabindex="-1" href="#" dltype="image/png">PNG</a></li>
        <li><a tabindex="-1" href="#" dltype="application/pdf">PDF</a></li>
        <li><a tabindex="-1" href="#" dltype="image/svg+xml">SVG</a></li>
    </ul>
</div>
</div>
<form method="post" action="http://export.highcharts.com/" id="imageGetForm">
    <input type="hidden" name="filename" id="imageFilename" value="" />
    <input type="hidden" name="type" id="imageGetFormTYPE" value="" />
    <input type="hidden" name="width" value="900" />
    <input type="hidden" name="svg" value="" id="imageGetFormSVG" />
</form>
</div>
</body>
</html>